package com.jzo2o.foundations.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jzo2o.common.expcetions.CommonException;
import com.jzo2o.common.expcetions.ForbiddenOperationException;
import com.jzo2o.common.model.PageResult;
import com.jzo2o.foundations.enums.FoundationStatusEnum;
import com.jzo2o.foundations.mapper.RegionMapper;
import com.jzo2o.foundations.mapper.ServeItemMapper;
import com.jzo2o.foundations.model.domain.Region;
import com.jzo2o.foundations.model.domain.Serve;
import com.jzo2o.foundations.mapper.ServeMapper;
import com.jzo2o.foundations.model.domain.ServeItem;
import com.jzo2o.foundations.model.domain.ServeType;
import com.jzo2o.foundations.model.dto.request.ServePageQueryReqDTO;
import com.jzo2o.foundations.model.dto.request.ServeUpsertReqDTO;
import com.jzo2o.foundations.model.dto.response.ServeResDTO;
import com.jzo2o.foundations.service.IServeService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jzo2o.mysql.utils.PageHelperUtils;
import com.jzo2o.mysql.utils.PageUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;

/**
 * <p>
 * 服务表 服务实现类
 * </p>
 *
 * @author zty
 * @since 2025-05-27
 */
@Service
public class ServeServiceImpl extends ServiceImpl<ServeMapper, Serve> implements IServeService {
@Resource
private ServeMapper serveMapper;
@Resource
private RegionMapper  regionMapper;
@Resource
private ServeItemMapper serveItemMapper;
    @Override
    public PageResult<ServeResDTO> page(ServePageQueryReqDTO dto) {
        return PageHelperUtils.selectPage(dto, () -> baseMapper.selectServeListByRegionId(dto.getRegionId())
        );
    }
/**
 * 删除服务
 */
    @Override
    public void deleteById(Long id) {
        //如果区域服务当前状态为草稿，则删除，否则无法删除，售卖状态，0：草稿，1下架，2上架
        Serve serve = baseMapper.selectById(id);
        if (serve == null){
            throw new ForbiddenOperationException("服务不存在");
        }
        if (serve.getSaleStatus() == FoundationStatusEnum.INIT.getStatus()) {
            baseMapper.deleteById(id);
        } else {
            throw new ForbiddenOperationException("当前状态为非草稿，不允许删除");
        }
    }
/**
 * 批量添加服务
 */
    @Override
    public void add(List<ServeUpsertReqDTO> list) {
        for (ServeUpsertReqDTO dto : list){
            //健壮性判断
            //1.查询服务项，如果为空，则抛出异常
            ServeItem serveItem = serveItemMapper.selectById(dto.getServeItemId());
            if (serveItem == null){
                throw new ForbiddenOperationException("服务项不存在");
            }
            //2.查询服务项所属的服务状态，如果为未启用，则抛出异常
            //注意这里不能写2，代码中尽量避免魔法值（没头没尾突然出现的值）
            //解决方式：1.定义到常量里，取常量值，2.定义到枚举中，取枚举值
            if (serveItem.getActiveStatus() != FoundationStatusEnum.ENABLE.getStatus()){
                throw new ForbiddenOperationException(serveItem.getName() +"服务不可用");
            }
            //3.查询区域，如果当前区域已经有这个服务了，不允许重复添加
            //查询当前区域服务数量
            Integer count = lambdaQuery()
                    .eq(Serve::getRegionId, dto.getRegionId())
                    .eq(Serve::getServeItemId, dto.getServeItemId())
                    .count();
            if (count > 0){
                throw new ForbiddenOperationException(serveItem.getName() +"服务项已存在");
            }

            //把数据封装成Serve对象,插入到serve表
            Serve serve = BeanUtil.toBean(dto, Serve.class);
            //获取当前区域的citycode，首先要根据id获取到对象，然后再由对象来获取区域编码
            Region region = regionMapper.selectById(dto.getRegionId());
            //设置服务的城市编码
            serve.setCityCode(region.getCityCode());
            save(serve);
        }
    }

    /**
     * 修改区域服务价格
     * @param id
     * @param price
     */
    @Override
    public void updatePriceById(Long id, BigDecimal price) {
        //方式一：使用lambdaUpdate
        boolean updated = lambdaUpdate()
                .set(Serve::getPrice, price)
                .eq(Serve::getId, id)
                .update();
        if (!updated) {
            throw new CommonException("修改服务价格失败");
        }
     /*
     //方式二：使用原生sql
      Serve serve = serveMapper.selectById(id);
        serve.setPrice(price);
        serveMapper.updateById(serve);*/
    }
/**
 * 区域服务上架功能
 */
    @Override
    public void OnSale(Long id) {
        //1.先判断区域服务状态是否为草稿或下架，是才能上架
        Serve serve = baseMapper.selectById(id);
        if (serve==null){
            throw new ForbiddenOperationException("服务不存在");
        }
        if (serve.getSaleStatus() != FoundationStatusEnum.INIT.getStatus() && serve.getSaleStatus() != FoundationStatusEnum.DISABLE.getStatus()) {
            throw new ForbiddenOperationException("当前状态为非草稿或下架，不允许上架");
        }else {
            //2.如果条件已成立，再判断该服务项是否启用，启用才能上架
            ServeItem serveItem = serveItemMapper.selectById(serve.getServeItemId());
            if (serveItem == null) {
                throw new ForbiddenOperationException("服务项不存在");
            }
            if (serveItem.getActiveStatus() != FoundationStatusEnum.ENABLE.getStatus()) {
                throw new ForbiddenOperationException(serveItem.getName() + "服务项未启用，不允许上架");
            }else {
                boolean update = lambdaUpdate()
                        .set(Serve::getSaleStatus, FoundationStatusEnum.ENABLE.getStatus())
                        .eq(Serve::getId, id)
                        .update();
                if (!update) {
                    throw new CommonException("修改服务状态失败");
                }
            }
        }
    }
/**
 * 区域服务下架功能
 */
    @Override
    public void offSale(Long id) {
        //1.先判断区域服务状态是否为启用，是才能下架
        Serve serve = baseMapper.selectById(id);
        if (serve==null){
            throw new ForbiddenOperationException("服务不存在");
        }
        if (serve.getSaleStatus() == FoundationStatusEnum.ENABLE.getStatus()) {
            boolean update = lambdaUpdate()
                    .set(Serve::getSaleStatus, FoundationStatusEnum.DISABLE.getStatus())
                    .eq(Serve::getId, id)
                    .update();
            if (!update) {
                throw new CommonException("修改服务状态失败");
            }
        }else {
            throw new ForbiddenOperationException("当前状态为非启用，不允许下架");
        }
    }

    /**
     * 区域服务设为热门服务
     * @param id
     */
    //只有上架状态才可以设置热门
    @Override
    public void onHot(Long id) {
        Serve serve = baseMapper.selectById(id);
        if (serve==null){
            throw new ForbiddenOperationException("服务不存在");
        }
        //2.如果当前服务状态为未上架，才可以设置为热门服务
        if (serve.getSaleStatus() != FoundationStatusEnum.ENABLE.getStatus()) {
            throw new ForbiddenOperationException("当前服务状态为未上架，不允许设为热门服务");
        }
        if (serve.getIsHot() == 1) {
            throw new ForbiddenOperationException("该服务已设为热门服务");
        }
        boolean update = lambdaUpdate()
                .set(Serve::getIsHot, 1)
                .eq(Serve::getId, id)
                .update();
                if (!update) {
                    throw new CommonException("修改服务状态失败");
                }
    }
/**
 * 区域服务取消设为热门服务
 * @param id
 */
//我的业务理解：只有在上架状态，才可以设置热门服务
    @Override
    public void offHot(Long id) {
        Serve serve = baseMapper.selectById(id);
        if (serve==null){
            throw new ForbiddenOperationException("服务不存在");
        }
        //如果当前服务状态为启用，才可以取消热门服务
        if (serve.getSaleStatus() != FoundationStatusEnum.ENABLE.getStatus()) {
            throw new ForbiddenOperationException("当前服务状态为未上架，不允许设为热门服务");
        }
        if (serve.getIsHot() == 0) {
            throw new ForbiddenOperationException("该服务已取消设为热门服务");
        }
        boolean update = lambdaUpdate()
                .set(Serve::getIsHot, 0)
                .eq(Serve::getId, id)
                .update();
                if (!update) {
                    throw new CommonException("修改服务状态失败");
                }
    }

/*    @Override
    public PageResult<ServeResDTO> page(ServePageQueryReqDTO dto) {
        return PageHelperUtils.selectPage(dto, new PageHelperUtils.QueryExecutor<ServeResDTO>() {

                    @Override
                    public List<ServeResDTO> query() {
                        return baseMapper.selectServeListByRegionId(dto.getRegionId());
                    }
                }
        );
    }*/
}
